package repository

import (
	"context"
	"hh/practice/internal/domain"
	"hh/practice/internal/repository/dao"
)

var (
	ErrUserDuplicateEmail  = dao.ErrUserDuplicateEmail
	ErrUserNotFound        = dao.ErrUserNotFound
	ErrUserProfileNotFound = dao.ErrUserProfileNotFound
)

type UserRepository struct {
	dao *dao.UserDAO
}

func NewUserRepository(dao *dao.UserDAO) *UserRepository {
	return &UserRepository{dao: dao}
}

func (repo *UserRepository) Create(c context.Context, u domain.User) error {
	return repo.dao.Insert(c, dao.User{
		Email:    u.Email,
		Password: u.Password,
	})
}

func (repo *UserRepository) FindeByEmail(ctx context.Context, email string) (domain.User, error) {
	u, err := repo.dao.FindByEmail(ctx, email)
	if err != nil {
		return domain.User{}, err
	}
	du := toDomainUser(u)
	return du, nil
}

func (repo *UserRepository) FindProfileByUid(c context.Context, uid int64) (domain.UserProfile, error) {
	up, err := repo.dao.FindProfileByUid(c, uid)
	if err != nil {
		return domain.UserProfile{}, err
	}
	dup := toDomainUserProfile(up)
	return dup, nil
}

func (repo *UserRepository) FindProfileByName(c context.Context, name string) (domain.UserProfile, error) {
	up, err := repo.dao.FindProfileByName(c, name)
	if err != nil {
		return domain.UserProfile{}, err
	}
	dup := toDomainUserProfile(up)
	return dup, nil
}

func (repo *UserRepository) CreateUserProfile(ctx context.Context, profile domain.UserProfile) error {
	return repo.dao.CreateUserProfile(ctx, dao.UserProfile{
		Uid:   profile.Uid,
		Name:  profile.Name,
		Birth: profile.Birth,
		Intro: profile.Intro,
	})
}

func (repo *UserRepository) UpdateUserProfile(ctx context.Context, profile domain.UserProfile) error {
	return repo.dao.UpdateUserProfile(ctx, dao.UserProfile{
		Id:    profile.Id,
		Uid:   profile.Uid,
		Name:  profile.Name,
		Birth: profile.Birth,
		Intro: profile.Intro,
	})
}

func toDomainUserProfile(up dao.UserProfile) domain.UserProfile {
	return domain.UserProfile{
		Id:    up.Id,
		Uid:   up.Uid,
		Name:  up.Name,
		Birth: up.Birth,
		Intro: up.Intro,
	}
}

func toDomainUser(u dao.User) domain.User {
	var du domain.User
	du.Email = u.Email
	du.Password = u.Password
	du.Id = u.Id
	return du
}
